<?php

namespace App\Http\Controllers\Cashbook\Merchant;

use App\Http\Controllers\BaseController;
use App\Models\Cashbook\CashbookCycleModel;
use App\Models\Cashbook\CashbookModel;
use App\Service\BaseService;
use App\Service\Cashbook\CashbookService;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class CashbookController extends BaseController
{
    /**
     * 总览
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function total(Request $request): JsonResponse
    {
        $userId    = (string)$request->get('userId', '');
        $type      = (int)$request->get('type', 0);
        $category  = (string)$request->get('category', '');
        $startTime = (string)$request->get('startTime', '');
        $endTime   = (string)$request->get('endTime', '');
        $shopId    = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        if ($category) {
            $category = explode(',', $category);
        }
        if ($userId !== "") {
            $userId = explode(',', $userId);
        }
        return $this->success(CashbookService::total($userId, $shopId, $type, $category, $startTime, $endTime));
    }

    /**
     * 列表
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function list(Request $request): JsonResponse
    {
        $pageSize  = $request->get('pageSize', 20);
        $pageNum   = $request->get('pageNum', 1);
        $userId    = (string)$request->get('userId', '');
        $type      = (int)$request->get('type', 0);
        $category  = (string)$request->get('category', 0);
        $startTime = (string)$request->get('startTime', '');
        $endTime   = (string)$request->get('endTime', '');
        $shopId    = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        if ($category) {
            $category = explode(',', $category);
        }
        if ($userId !== "") {
            $userId = explode(',', $userId);
        }
        return $this->success(CashbookService::lists($userId, $shopId, $type, $category, $startTime, $endTime, $pageNum, $pageSize));
    }

    /**
     * 详情
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function detail(Request $request, int $id): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        return $this->success(CashbookService::detail($shopId, $id));
    }

    /**
     * 记一笔
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function add(Request $request): JsonResponse
    {
        $this->validate(
            $request, [
                'type'     => 'required|integer',
                'date'     => 'required|date',
                'category' => 'required|integer',
                'amount'   => 'required|numeric',
            ]
        );
        if (!in_array($request->type, array_keys(CashbookModel::TYPE_TEXT_MAPPING))) {
            return BaseService::throwErr("type类型错误");
        }
        if (!in_array($request->category, array_keys(CashbookModel::CATEGORY_TEXT_MAPPING_ALL))) {
            return BaseService::throwErr("category类型错误");
        }
        $remark = (string)$request->get('remark', '');
        $img    = (array)$request->get('img', []);
        $shopId = (int)$request->header('shopId', 0);
        $userId = getRmsUserId();
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        if (strtotime($request->date) > strtotime(date('Y-m-d'))) {
            return BaseService::throwErr("时间不能大于当前日期");
        }
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::add($shopId, $request->type, $request->date, $request->category, $request->amount, $remark, $img, $userId);
        return $this->success();
    }

    /**
     * 修改
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function update(Request $request, int $id): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $date     = (string)$request->get('date', '');
        $type     = (int)$request->get('type', 0);
        $category = (int)$request->get('category', 0);
        $amount   = $request->get('amount', 0);
        $remark   = (string)$request->get('remark', 0);
        $img      = (array)$request->get('img', []);
        if (!in_array($type, array_keys(CashbookModel::TYPE_TEXT_MAPPING))) {
            return BaseService::throwErr("type类型错误");
        }
        if (!in_array($category, array_keys(CashbookModel::CATEGORY_TEXT_MAPPING_ALL))) {
            return BaseService::throwErr("category类型错误");
        }
        $userId = getRmsUserId();
        if ($date && strtotime($date) > strtotime(date('Y-m-d'))) {
            return BaseService::throwErr("时间不能大于当前日期");
        }
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::update($shopId, $id, $date, $type, $category, $amount, $remark, $img, $userId);
        return $this->success();
    }

    /**
     * 删除
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function delete(Request $request, int $id): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $userId = getRmsUserId();
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::delete($shopId, $id, $userId);
        return $this->success();
    }

    /**
     * 同步开关列表
     * @param Request $request
     * @return JsonResponse
     */
    public function switchList(Request $request): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        return $this->success(CashbookService::switchList($shopId));
    }

    /**
     * 同步开关编辑
     * @param Request $request
     * @return JsonResponse
     * @throws ValidationException
     */
    public function switchUpdate(Request $request): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $this->validate(
            $request, [
                'data' => 'required|array',
            ]
        );
        $userId = getRmsUserId();
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::switchUpdate($shopId, $request->data, $userId);
        return $this->success();
    }

    /**
     * 周期记录列表
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function cycleList(Request $request): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $userId = getRmsUserId();
        return $this->success(CashbookService::cycleList($shopId, $userId));
    }

    /**
     * 周期记录详情
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function cycleDetail(Request $request, int $id): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        return $this->success(CashbookService::cycleDetail($shopId, $id));
    }

    /**
     * 周期记录编辑
     * @param Request $request
     * @return JsonResponse
     */
    public function cycleUpdate(Request $request): JsonResponse
    {
        $this->validate(
            $request, [
                'cycleType' => 'required|integer',
                'type'      => 'required|integer',
                'category'  => 'required|integer',
                'amount'    => 'required|numeric',
                'startTime' => 'required|date',
                'endTime'   => 'required|date',
            ]
        );
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        if (!in_array($request->type, array_keys(CashbookModel::TYPE_TEXT_MAPPING))) {
            return BaseService::throwErr("type类型错误");
        }
        if (!in_array($request->category, array_keys(CashbookModel::CATEGORY_TEXT_MAPPING_ALL))) {
            return BaseService::throwErr("category类型错误");
        }
        if (!in_array($request->cycleType, array_keys(CashbookCycleModel::CYCLE_TYPE_TEXT_MAPPING))) {
            return BaseService::throwErr("cycleType类型错误");
        }
        if (strtotime($request->startTime) >= strtotime($request->endTime)) {
            return BaseService::throwErr("结束时间应大于开始时间");
        }
        $id     = (int)$request->get('id', 0);
        $remark = (string)$request->get('remark', '');
        $userId = getRmsUserId();
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::cycleUpdate(
            $shopId, $userId, $id, $request->cycleType, $request->type, $request->category, $remark,
            $request->amount, $request->startTime, $request->endTime
        );
        return $this->success();
    }

    /**
     * 周期记录删除
     * @param Request $request
     * @param int $id
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function cycleDelete(Request $request, int $id): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $userId = getRmsUserId();
        if (!CashbookService::isShopStaff($shopId, $userId)) {
            return BaseService::throwErr("非本门店员工不可操作");
        }
        CashbookService::cycleDelete($shopId, $id, $userId);
        return $this->success();
    }

    /**
     * 记账本数据手动同步
     * @param Request $request
     * @return JsonResponse
     * @throws GuzzleException
     */
    public function manualUpdate(Request $request): JsonResponse
    {
        $shopId = (int)$request->header('shopId', 0);
        if (!$shopId) {
            return BaseService::throwErr("shopId错误");
        }
        $this->validate(
            $request, [
                'id' => 'required|integer',
            ]
        );
        $userId = getRmsUserId();
        CashbookService::manualUpdate($shopId, $request->id, $userId);
        return $this->success();
    }
}
